home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------------
-
- apputil.c
-
- This reusable module contains utility routines for finding and running helper
- applications.
-
- Adapted from DTS sample code "SignatureToApp" and "LaunchWithDoc"
-
- ----------------------------------------------------------------------------*/
-
- #include <string.h>
- #include <Aliases.h>
- #include <AppleEvents.h>
- #include <Folders.h>
- #include <Processes.h>
- #include <stdio.h>
-
- #include "def.h"
- #include "apputil.h"
- #include "memutil.h"
- #include "fileutil.h"
- #include "strutil.h"
- #include "resutil.h"
-
-
-
- /*----------------------------------------------------------------------------
- FindRunningAppBySignature
-
- Find a running app given its signature.
-
- Entry: sig = signature of app.
-
- Exit: function result = error code.
- = procNotFound if not running.
- *fSpec = file spec of app.
- *psn = process serial number of running app.
- ----------------------------------------------------------------------------*/
-
- static OSErr FindRunningAppBySignature (OSType sig, FSSpec *fSpec,
- ProcessSerialNumber *psn)
- {
- OSErr err = noErr;
- ProcessInfoRec info;
-
- psn->highLongOfPSN = 0;
- psn->lowLongOfPSN = kNoProcess;
- while (true) {
- err = GetNextProcess(psn);
- if (err != noErr) return err;
- info.processInfoLength = sizeof(info);
- info.processName = nil;
- info.processAppSpec = fSpec;
- err = GetProcessInformation(psn, &info);
- if (err != noErr) return err;
- if (info.processSignature == sig) return noErr;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- VolHasDesktopDB
-
- Check to see if a volume supports the new desktop database.
-
- Entry: vRefNum = vol ref num of volumn
-
- Exit: function result = error code.
- *hasDesktop = true if volume has the new desktop database.
- ----------------------------------------------------------------------------*/
-
- static OSErr VolHasDesktopDB (short vRefNum, Boolean *hasDesktop)
- {
- HParamBlockRec pb;
- GetVolParmsInfoBuffer info;
- OSErr err = noErr;
-
- pb.ioParam.ioCompletion = nil;
- pb.ioParam.ioNamePtr = nil;
- pb.ioParam.ioVRefNum = vRefNum;
- pb.ioParam.ioBuffer = (Ptr)&info;
- pb.ioParam.ioReqCount = sizeof(info);
- err = PBHGetVolParmsSync(&pb);
- *hasDesktop = err == noErr && (info.vMAttrib & (1L << bHasDesktopMgr)) != 0;
- return err;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FindAppOnVolume
-
- Find an application on a volume.
-
- Entry: sig = application signature.
- vRefNum = vol ref num
-
- Exit: function result = error code
- = afpItemNotFound if app not found on vol.
- *file = file spec for application on volume.
- ----------------------------------------------------------------------------*/
-
- static OSErr FindAppOnVolume (OSType sig, short vRefNum, FSSpec *file)
- {
- DTPBRec pb;
- OSErr err = noErr;
- short ioDTRefNum, i;
- FInfo fInfo;
- FSSpec candidate;
- unsigned long lastModDateTime, maxLastModDateTime;
-
- memset(&pb, 0, sizeof(DTPBRec));
- pb.ioCompletion = nil;
- pb.ioVRefNum = vRefNum;
- pb.ioNamePtr = nil;
- err = PBDTGetPath(&pb);
- if (err != noErr) return err;
- ioDTRefNum = pb.ioDTRefNum;
-
- memset(&pb, 0, sizeof(DTPBRec));
- pb.ioCompletion = nil;
- pb.ioIndex = 0;
- pb.ioFileCreator = sig;
- pb.ioNamePtr = file->name;
- pb.ioDTRefNum = ioDTRefNum;
- err = PBDTGetAPPLSync(&pb);
-
- if (err == fnfErr || err == paramErr) return afpItemNotFound;
- if (err != noErr) return err;
-
- file->vRefNum = vRefNum;
- file->parID = pb.ioAPPLParID;
-
- err = FSpGetFInfo(file, &fInfo);
- if (err == noErr) return noErr;
-
- i = 1;
- maxLastModDateTime = 0;
- while (true) {
- memset(&pb, 0, sizeof(DTPBRec));
- pb.ioCompletion = nil;
- pb.ioIndex = i;
- pb.ioFileCreator = sig;
- pb.ioNamePtr = candidate.name;
- pb.ioDTRefNum = ioDTRefNum;
- err = PBDTGetAPPLSync(&pb);
- if (err != noErr) break;
- candidate.vRefNum = vRefNum;
- candidate.parID = pb.ioAPPLParID;
- err = GetLastModDateTime(file, &lastModDateTime);
- if (err == noErr) {
- if (lastModDateTime > maxLastModDateTime) {
- maxLastModDateTime = lastModDateTime;
- *file = candidate;
- }
- }
- i++;
- }
-
- return maxLastModDateTime > 0 ? noErr : afpItemNotFound;
- }
-
-
-
- /*----------------------------------------------------------------------------
- FindAppFromSig
-
- Find an application given its signature.
-
- Entry: sig = application signature
-
- Entry: running = nil to skip check for running app and just do
- a desktop database search for the disk file.
-
- Exit: function result = error code.
- = fnfErr if app not found
- *fSpec = file spec of application.
- *running = true if app is running.
- *psn = process serial number of app if running.
- ----------------------------------------------------------------------------*/
-
- OSErr FindAppFromSig (OSType sig, FSSpec *fSpec, Boolean *running,
- ProcessSerialNumber *psn)
- {
- OSErr err = noErr;
- short sysVRefNum, vRefNum, index;
- Boolean hasDesktopDB;
-
- if (running != nil) {
- err = FindRunningAppBySignature(sig, fSpec, psn);
- *running = true;
- if (err == noErr) return noErr;
- *running = false;
- if (err != procNotFound) return err;
- }
- err = GetSysVolume(&sysVRefNum);
- if (err != noErr) return err;
- vRefNum = sysVRefNum;
- index = 0;
- while (true) {
- if (index == 0 || vRefNum != sysVRefNum) {
- err = VolHasDesktopDB(vRefNum, &hasDesktopDB);
- if (err != noErr) return err;
- if (hasDesktopDB) {
- err = FindAppOnVolume(sig, vRefNum, fSpec);
- if (err != afpItemNotFound) return err;
- }
- }
- index++;
- err = GetIndVolume(index, &vRefNum);
- if (err == nsvErr) return fnfErr;
- if (err != noErr) return err;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- FindAppNameFromSig
-
- Find an application name given its signature.
-
- Entry: sig = application signature
-
- Exit: function result = error code.
- = fnfErr if app not found
- name = application name.
- ----------------------------------------------------------------------------*/
-
- OSErr FindAppNameFromSig (OSType sig, StringPtr name)
- {
- FSSpec fSpec;
- OSErr err = noErr;
-
- err = FindAppFromSig(sig, &fSpec, nil, nil);
- if (err != noErr) return err;
- CopyPascalString(name, fSpec.name);
- return noErr;
- }
-
-
-
- /*----------------------------------------------------------------------------
- LaunchAppWithDoc
-
- Launch an application with an initial open document event.
-
- Entry: running = true if application is running, in which case
- it is sent the odoc event.
- appSpec = file spec of application.
- *psn = process serial number of app if it is running.
- docSpec = file spec of document.
- launchFileFlags = file flags.
- launchControlFlags = control flags.
-
- Exit: function result = error code.
- ----------------------------------------------------------------------------*/
-
- OSErr LaunchAppWithDoc (Boolean running, FSSpec *appSpec, ProcessSerialNumber *psn,
- FSSpec *docSpec, unsigned short launchFileFlags, unsigned short launchControlFlags)
- {
- ProcessSerialNumber thePSN;
- LaunchParamBlockRec launchThis;
- AEDesc target = {0, nil};
- AEDesc docDesc = {0, nil};
- AEDesc launchDesc = {0, nil};
- AEDescList theList = {0, nil};
- AliasHandle withThis = nil;
- AppleEvent theEvent = {0, nil};
- AppleEvent theReply = {0, nil};
- OSErr err = noErr;
- Boolean autoParamValue = false;
-
- if (running) thePSN = *psn;
- err = AECreateDesc(typeProcessSerialNumber, &thePSN, sizeof(thePSN), &target);
- if (err != noErr) goto exit;
- err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &target,
- kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
- if (err != noErr) goto exit;
- err = AECreateList(nil, 0, false, &theList);
- if (err != noErr) goto exit;
- err = NewAlias(nil, docSpec, &withThis);
- if (err != noErr) goto exit;
- MyHLock(withThis);
- err = AECreateDesc(typeAlias, (Ptr)*withThis, MyGetHandleSize(withThis),
- &docDesc);
- if (err != noErr) goto exit;
- MyHUnlock(withThis);
- err = AEPutDesc(&theList, 0, &docDesc);
- if (err != noErr) goto exit;
- err = AEPutParamDesc(&theEvent, keyDirectObject, &theList);
- if (err != noErr) goto exit;
- if (running) {
- err = AESend(&theEvent, &theReply, kAENoReply, kAENormalPriority, kNoTimeOut,
- nil, nil);
- if (err != noErr) goto exit;
- if ((launchControlFlags & launchDontSwitch) == 0) {
- err = SetFrontProcess(psn);
- if (err != noErr) goto exit;
- }
- } else {
- err = AECoerceDesc(&theEvent, typeAppParameters, &launchDesc);
- if (err != noErr) goto exit;
- MyHLock(theEvent.dataHandle);
- launchThis.launchAppSpec = appSpec;
- launchThis.launchAppParameters = (AppParametersPtr)*launchDesc.dataHandle;
- launchThis.launchBlockID = extendedBlock;
- launchThis.launchEPBLength = extendedBlockLen;
- launchThis.launchFileFlags = launchFileFlags;